import functools


class MyDecorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("start")

        result = self.func(*args, **kwargs)

        print("end")

        return result


@MyDecorator
def test():
    print("test...")
    return 200


print(test, test())

###############################################################
# 有参数的装饰器
print()


class ParamDecorator:
    def __init__(self, name):
        self.name = name

    def __call__(self, func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print(f"start - {self.name}")
            result = func(*args, **kwargs)
            print(f"end - {self.name}")
            return result

        return wrapper


@ParamDecorator("Jack")
def my_test():
    print("my_test...")
    return 200


print(my_test, my_test())
print()


###############################################################
# 给类做装饰器
# 实例化之前想做点事情，可以用
def cls_decorator(cls):
    print("start class decorator...")

    @functools.wraps(cls)
    def wrapper(*args, **kwargs):
        print("start")
        obj = cls(*args, **kwargs)
        print("end")
        return obj

    return wrapper


@cls_decorator
class Person:
    ...


p = Person()
print(p)